package com.innovation.wjrpc.server;

import com.innovation.wjrpc.codec.Decoder;
import com.innovation.wjrpc.codec.Encoder;
import com.innovation.wjrpc.communication.HTTPTransportServer;
import com.innovation.wjrpc.communication.NettyTransportServer;
import com.innovation.wjrpc.handle.HTTPRequestHandler;
import com.innovation.wjrpc.handle.NettyRequestHandler;
import com.innovation.wjrpc.protocol.Request;
import com.innovation.wjrpc.protocol.Response;
import com.innovation.wjrpc.transport.RequestHandler;
import com.innovation.wjrpc.transport.TransportServer;
import com.innovation.wjrpc.util.ReflectionUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * @author innoyiya
 * @date 2021/9/7 20:05
 */
@Slf4j
public class RpcServer {

    private RpcServerConfig config;

    private TransportServer net;

    private Encoder encoder;

    private Decoder decoder;

    private ServiceManager manager;

    private ServiceInvoker invoker;




    public RpcServer(RpcServerConfig config) {
        this.config = config;

        this.net = ReflectionUtils.newInstance(config.getTransportClass());

        this.encoder = ReflectionUtils.newInstance(config.getEncoderClass());

        this.decoder = ReflectionUtils.newInstance(config.getDecoderClass());

        this.manager = new ServiceManager();
        this.invoker = new ServiceInvoker();

    }

    public <T> void register (Class<T> interfaceClass, T bean) {
        manager.register(interfaceClass, bean);
    }

    public void start() {

        if (config.getTransportClass() == NettyTransportServer.class) {
            this.net.init(config.getPort(), new NettyRequestHandler(decoder, encoder,manager, invoker));
        }else if (config.getTransportClass() == HTTPTransportServer.class) {
            this.net.init(config.getPort(), new HTTPRequestHandler(decoder, encoder,manager, invoker));
        }


        this.net.start();
    }

    public void stop() {
        this.net.stop();
    }


}